package com.wx.house.manager.api.Interceptor;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wx.house.common.util.RedisUtil;
import com.wx.house.core.pojo.po.SysAdminRole;
import com.wx.house.core.pojo.po.SysMenus;
import com.wx.house.core.pojo.vo.SysMenusVo;
import com.wx.house.core.pojo.vo.SysPermissionVo;

import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.github.pagehelper.util.StringUtil;
import com.wx.house.common.base.BaseController;
import com.wx.house.common.base.Constant;
import com.wx.house.common.exception.BusinessException;
import com.wx.house.common.exception.UserException;
import com.wx.house.common.util.JwtUtils;
import com.wx.house.manager.api.permission.service.SysAdminRoleService;
import com.wx.house.manager.api.permission.service.SysAdminService;
import com.wx.house.manager.api.permission.service.SysMenusService;

import io.jsonwebtoken.Claims;


public class LoginInterceptor extends BaseController implements HandlerInterceptor {

@Resource
private SysAdminService sysAdminService;
@Resource
private SysAdminRoleService sysAdminRoleService;
@Resource
private SysMenusService SysMenusService;
@Resource
private RedisUtil redisUtil;



/***
 * 进入
 */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception {
		//step1.
		//获取用户访问的url
		String requestURL = request.getRequestURL().toString();
		//获取用户访问的method
		String requestMethod = request.getMethod();
		SysPermissionVo sysPermissionVo=SysMenusService.SelectSysPermission(requestMethod);
		//step2.
		//获取用户token
		String token = request.getHeader("authorization");
		//step3.
		//去掉path参数，获取真正api
		if (!requestURL.endsWith("/")) {
		//  /accountcenter/department  =>   /accountcenter/
			requestURL = requestURL.replace(requestURL.split("/")[requestURL.split("/").length - 1], "");
		}
		//step4.
		List<SysMenus> selectRoleMenusAlllist = SysMenusService.findAdminMenulist();
		List<String> urlList = selectRoleMenusAlllist.stream().map(SysMenus::getUrl).distinct().collect(Collectors.toList());
		//不需要token校验的url
		List<String> a=new ArrayList<>();
		a.add("/DicWebDeploy");//网站配置
		a.add("/AdminLogin/Login/");// 用户登录
		a.add("/AdminLogin/LoginPhone/");// 用户短信登录
		a.add("/AdminLogin/getCode/");// 手机短信验证
		a.add("/AdminLogin/getPhone/");// 判断手机号是否存在
		a.add("/AdminLogin/getValiCode/");// 手机图片验证码
		a.add("/AdminLogin/logout/");// 退出登陆
		a.add("/common1/sms1/");// 短信验证码
		a.add("/base/validateCode/");// 图形验证码
		a.add("/company/areas/parent/");// 查询区域
		a.add("/AdminLogin/updateLogAdmin/");
		a.add("/DicWebDeploy");//网站配置
		//需要token校验但不需要验证用户的url
		List<String> b=new ArrayList<>();
		b.add("/dicbase/add/");//新增字典
		b.add("/dicbase/delete/");//基础字典表的删除
		b.add("/dicbase/findDic/");//获取系统字典
		b.add("/dicbase/list/");//查询字典下级目录
		b.add("/dicbase/search/");//查询字典详情
		b.add("/dicbase/update/");//基础字典表的更新
		b.add("/bBuildingbase");//房间读数比较
		//判断requestURL是否存在，如果不存在放行，如果存在进行校验是否有权限
		for (int i = 0; i < selectRoleMenusAlllist.size(); i++) {
			if(urlList.stream().anyMatch(requestURL::contains)) {
				//不需要token的url链接放行
				if(a.stream().anyMatch(requestURL::contains)) {
					return HandlerInterceptor.super.preHandle(request, response, handler);
				}
				
				Claims claims = null;
				try {
					claims = JwtUtils.builder().token(token).build().claims();
					} catch (Exception e) {
					e.printStackTrace();
					response.setStatus(601);
					throw new UserException("您的登录已过期",601);
				}
				
				//解析用户token
				String adminId = claims.get("id").toString();
				String accountType = claims.get("accountType").toString();
				String mAccId = claims.get("mAccId").toString();
				String redisToken=null;
				if("0".equals(mAccId)) {
					redisToken =redisUtil.get(String.format(Constant.REDIS_LOGIN_TOKEN, adminId, ""));
				}
				else {
					redisToken =redisUtil.get(String.format(Constant.REDIS_LOGIN_TOKEN, mAccId, adminId));
				}
				
				//判断token是否一致，如果不一致提示：您已经被迫下线
				if(!token.equals(redisToken)) {
					response.setStatus(602);
					throw new UserException("您已被迫下线",602);
				}
				
				//根据用户所在的全部角色，获取所有能访问的url和method
				List<SysAdminRole> selectAdminId=sysAdminRoleService.selectAdminIdRole(adminId);
				if (ObjectUtils.isEmpty(selectAdminId)) {
					response.setStatus(604);
					throw new UserException("用户未拥有任何角色,请先配置角色",604);
				}
				
				if (StringUtil.isEmpty(token)) {
					response.setStatus(600);
					throw new UserException("用户token不能为空", 600);
				}
				//不需要token的url链接放行
				if(b.stream().anyMatch(requestURL::contains)) {
					return HandlerInterceptor.super.preHandle(request, response, handler);
				}
				List<SysMenusVo> selectRoleMenusAll = SysMenusService.selectRoleMenusAll(adminId);
				List<String> AdminUrlList = selectRoleMenusAll.stream().map(SysMenusVo::getUrl).distinct().collect(Collectors.toList());
				for (int k = 0; k < selectRoleMenusAll.size(); k++) {
					if(AdminUrlList.stream().anyMatch(requestURL::contains)) {
						List<String> result = Arrays.asList(selectRoleMenusAll.get(i).getPermissionId().split(","));
						for (int j = 0; j < result.size(); j++) {
							//判断用户是否有GET,POST,PUT,DELETE权限
							if(sysPermissionVo.getId().contains(result.get(j))) {
								return HandlerInterceptor.super.preHandle(request, response, handler);
							}
						}	
					}
					else {
						response.setStatus(666);
						throw new UserException("您的权限不足",666);
					}
				}
			}
			//判断用户是否拥有此requestURL权限
			else {
				return HandlerInterceptor.super.preHandle(request, response, handler);
			}
		}
		throw new UserException("拦截器错误",700);
}

/***
 * 调用完成后
 */
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                       ModelAndView modelAndView) throws Exception {
//		System.out.println("拦截器-postHandle:controller方法之后,视图渲染之前...");
//		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}

/***
 * 完成之后，用于资源清理
 */
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
		throws Exception {
//	 	System.out.println("拦截器-视图渲染后:资源清理...");
//		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
	
}
